package com.wedo.mall;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.support.annotation.Nullable;
import android.util.Log;

import com.google.android.gms.maps.model.LatLng;
import com.hyphenate.easeui.map.AddressService;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 请求路线规划
 * Created by e on 2017/10/9.
 *http://blog.csdn.net/gf771115/article/details/25713063
 * https://maps.googleapis.com/maps/api/directions/json?origin=39.99709957757345,116.31184045225382&destination=39.949158391497214,116.4154639095068&sensor=false&mode=driving
 */

public class RouteService extends IntentService {

    private static final String TAG = "RouteService";
    private ResultReceiver mReceiver;

    public static void route(Context context,ResultReceiver receiver, String fromLat, String fromLng, String toLat, String toLng){
        Intent intent = new Intent(context,RouteService.class);
        intent.putExtra(AddressService.EXTRA_RECEIVER,receiver);
        intent.putExtra("fromLat",fromLat);
        intent.putExtra("fromLng",fromLng);
        intent.putExtra("toLat",toLat);
        intent.putExtra("toLng",toLng);
        context.startService(intent);
    }

    public RouteService() {
        super("RouteService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        mReceiver = intent.getParcelableExtra(AddressService.EXTRA_RECEIVER);
        if (mReceiver == null) {
            return;
        }

        String fromLat = intent.getStringExtra("fromLat");
        String fromLng = intent.getStringExtra("fromLng");
        String toLat = intent.getStringExtra("toLat");
        String toLng = intent.getStringExtra("toLng");

        StringBuilder url = new StringBuilder();
        url.append("https://maps.googleapis.com/maps/api/directions/json?");
        url.append("origin=").append(fromLat).append(",").append(fromLng);
        url.append("&destination=").append(toLat).append(",").append(toLng);
        url.append("&sensor=false&mode=driving");
        //url.append("&");

        Log.i(TAG,url.toString());

        OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(15, TimeUnit.SECONDS)
                .connectTimeout(15,TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder().url(url.toString()).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                String error = getResources().getString(com.hyphenate.easeui.R.string.ease_google_service_invalid);
                Bundle bundle = new Bundle();
                bundle.putString("error",error);
                mReceiver.send(-1,bundle);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                Log.i(TAG,json);
                Bundle bundle = new Bundle();
                bundle.putString("json",json);
                mReceiver.send(1,bundle);
            }
        });
    }

    /**
     * Receives a JSONObject and returns a list of lists containing latitude and
     * longitude
     */
    public static List<List<HashMap<String, String>>> parse(String json) {

        List<List<HashMap<String, String>>> routes = new ArrayList<>();
        JSONArray jRoutes = null;
        JSONArray jLegs = null;
        JSONArray jSteps = null;

        try {

            JSONObject jObject = new JSONObject(json);
            jRoutes = jObject.getJSONArray("routes");

            /** Traversing all routes */
            for (int i = 0; i < jRoutes.length(); i++) {
                jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
                List path = new ArrayList<HashMap<String, String>>();

                /** Traversing all legs */
                for (int j = 0; j < jLegs.length(); j++) {
                    jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");

                    /** Traversing all steps */
                    for (int k = 0; k < jSteps.length(); k++) {
                        String polyline = "";
                        polyline = (String) ((JSONObject) ((JSONObject) jSteps
                                .get(k)).get("polyline")).get("points");
                        List<LatLng> list = decodePoly(polyline);

                        /** Traversing all points */
                        for (int l = 0; l < list.size(); l++) {
                            HashMap<String, String> hm = new HashMap<String, String>();
                            hm.put("lat",
                                    Double.toString(((LatLng) list.get(l)).latitude));
                            hm.put("lng",
                                    Double.toString(((LatLng) list.get(l)).longitude));
                            path.add(hm);
                        }
                    }
                    routes.add(path);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
        }
        return routes;
    }

    /**
     * Method to decode polyline points Courtesy :
     * jeffreysambells.com/2010/05/27
     * /decoding-polylines-from-google-maps-direction-api-with-java
     * */
    private static List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<LatLng>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }
        return poly;
    }
}
